import {
  type Ref,
  shallowRef,
  ref,
  computed,
  watch,
  toValue,
  type ComputedRef
} from 'vue';
import {
  Options,
  Column,
  DataSource,
  Props,
  Record
} from './type';
import { message } from 'ant-design-vue';
import { getValueByModel, setValueByModel } from "./util"

export default class {
  table: Ref<Element | null | undefined> = shallowRef();
  columns: Ref<Column[]> = ref([]);
  dataSource: Ref<DataSource[]> = ref([]);
  props: Props;
  emits: any;
  checkNoRepaeatRowKeyTimer: any;

  constructor(options: Options){
    Object.assign(this, options);
    
    //检测数据是否重复，会消耗性能，非必要场景，不建议开启检测
    if (options.props.checkNoRepaeatRowKey || location.href.includes('checkNoRepaeatRowKey')){
      watch(() => options.dataSource.value.length, (length: number) => {
        this.checkNoRepaeatRowKey(length);
      })
    }
  }

  warningMsg(msg: string){
    message.warning(msg)
    this.emits('warning', msg)
  }

  getValueByModel = getValueByModel
  setValueByModel = setValueByModel

  getMessage(str: string): ComputedRef<string>{
    return computed(() => getValueByModel(str.split('.'), this.props.messageConfig ?? {}) ?? '')
  }

  checkHasReadonly(records: Record[]){
    if (this.props.readonly === true) return true;
    if (Array.isArray(this.props.readonly)) return !!this.props.readonly.find(rowKey => !!records?.find?.((row : Record) => row[this.props.rowKey] === rowKey))
  }
  checkHasDisable(records: Record[]){
    if (this.props.disabled === true) return true;
    if (Array.isArray(this.props.disabled)) return !!this.props.disabled.find(rowKey => !!records?.find?.((row : Record) => row[this.props.rowKey] === rowKey))
  }
  checkNoRepaeatRowKey(length: number){
    clearTimeout(this.checkNoRepaeatRowKeyTimer)
    this.checkNoRepaeatRowKeyTimer = null;
    this.checkNoRepaeatRowKeyTimer = setTimeout(() => {
      const keys = Array.from(new Set( toValue(this.props.dataSource)?.map(row => row[this.props.rowKey])))
      if (keys.length !== length) {
        const sameKeys: string[] = []
        toValue(this.props.dataSource)?.forEach((row, index) => {
          const currentKey = row[this.props.rowKey]
          if (keys[index] !== currentKey) {
            sameKeys.push(currentKey);
            keys.splice(index, 0, currentKey);
          }
        })
        throw `表格数据检测出重复的 ${this.props.rowKey} 数据 ${sameKeys.join('、')}，为了渲染不会出错，key值必须唯一, 请检查数据.`
      }
    }, 0)
  }

  getCellElement({rowindex, colindex}: {
    rowindex?: number,
    colindex?: number,
  }): HTMLElement | undefined | null {
    if (rowindex === undefined && colindex === undefined) return undefined;

    if (rowindex !== undefined && colindex !== undefined) {
      return this.table.value?.querySelector(`td[data-rowindex='${rowindex}'][data-colindex='${colindex}']`)
    }

    if (rowindex === undefined) {
      return this.table.value?.querySelector(`th[data-colindex='${colindex}']`)
    }

    if (colindex === undefined) {
      return this.table.value?.querySelector(`tr[data-rowindex='${rowindex}']`)
    }

    return undefined;

  }
}